package com.shuma.shopmanage.draftmodule.service.serviceImpl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuma.shopmanage.common.exception.ShopManageException;
import com.shuma.shopmanage.common.model.LoginUser;
import com.shuma.shopmanage.common.result.ResultCodeEnum;
import com.shuma.shopmanage.common.utils.RedisConstants;
import com.shuma.shopmanage.common.utils.RedisWorker;
import com.shuma.shopmanage.draftmodule.mapper.GoodsDraftMapper;
import com.shuma.shopmanage.model.draft.model.GoodsDraft;
import com.shuma.shopmanage.model.draft.model.NonDeliverableCityDraft;
import com.shuma.shopmanage.model.draft.model.StoragecitiesDraft;
import com.shuma.shopmanage.model.draft.model.vo.GoodsDraftVo;
import com.shuma.shopmanage.model.shop.dto.GoodsDto;
import com.shuma.shopmanage.draftmodule.service.GoodsDraftService;
import com.shuma.shopmanage.draftmodule.service.NonDeliverableCityDraftService;
import com.shuma.shopmanage.draftmodule.service.StoragecitiesDraftService;
import com.shuma.shopmanage.model.shop.dto.PageDto;
import com.shuma.shopmanage.model.shop.vo.GoodsVo;
import com.shuma.shopmanage.model.shop.vo.PageVo;
import com.shuma.shopmanage.security.SecurityContextHolder;
import com.shuma.shopmanage.shopmodule.userFeign.UserFeignService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsDraftServiceImpl extends ServiceImpl<GoodsDraftMapper, GoodsDraft> implements GoodsDraftService {

    @Autowired
    private NonDeliverableCityDraftService nonDeliverableCityDraftService;

    @Autowired
    private StoragecitiesDraftService storagecitiesDraftService;

    List<NonDeliverableCityDraft> nonDeliverableCityList;

    List<StoragecitiesDraft> storagecitiesList;

    @Autowired
    private RedisWorker redisWorker;

    @Autowired
    private UserFeignService userFeignService;

    @Autowired
    GoodsDraftMapper goodsDraftMapper;

    @Transactional
    public GoodsVo insertGoodDraft(GoodsDto goodsDto) {
        GoodsDraft goodsDraft = BeanUtil.copyProperties(goodsDto, GoodsDraft.class);
        //判断草稿id是否为空
        Long id = goodsDto.getGoodsDraftId();
        //添加草稿
        LoginUser loginUser = SecurityContextHolder.getLoginUser();
        if(id == null){
            goodsDraft.setCreateUserId(loginUser.getId());
            goodsDraft.setManageUserId(loginUser.getId());
            Long keyId = redisWorker.nextId(RedisConstants.SHOPDRAFT_ID_KEY);
            goodsDraft.setId(keyId);
        }
        //修改草稿
        else {
            if(goodsDto.getManageUserId() != loginUser.getId()){
                throw new ShopManageException("不能操作此商品,",ResultCodeEnum.FAIL.getCode());
            }
            storagecitiesDraftService.removeByGoodsDraftId(id);
            nonDeliverableCityDraftService.removeByGoodsDraftId(id);
        }

        saveOrUpdate(goodsDraft);
        saveNonDeliverableCityList(goodsDraft,goodsDto.getNoDeliverPostalCodes());
        saveStorageList(goodsDraft,goodsDto.getStoragePostalCodes());
        GoodsVo goodsVo = BeanUtil.copyProperties(goodsDraft,GoodsVo.class);
        goodsVo.setGoodsDraftId(goodsDto.getId());
        return goodsVo;
    }

    /**
     * 分页查询所有草稿
     * @param pageDto 分页参数
     */
    @Override
    public PageVo queryPage(PageDto pageDto) {
        Page<GoodsDraft> pageParam = new Page<>();
        BeanUtils.copyProperties(pageDto, pageParam);
        QueryChainWrapper<GoodsDraft> wrapper = query();
        Page<GoodsDraft> pageResult = wrapper.page(pageParam);

        PageVo<GoodsDraftVo> goodsDraftVo = page(pageResult);

        return goodsDraftVo;
    }

    /**
     * 根据用户id分页查询草稿
     * @param pageDto 分页参数
     */
    @Override
    public PageVo<GoodsDraftVo> queryPageByUid(PageDto pageDto, Long id) {
        Page<GoodsDraft> pageParam = new Page<>();
        BeanUtils.copyProperties(pageDto, pageParam);
        QueryChainWrapper<GoodsDraft> wrapper = query()
                .eq("createUserId", id);
        Page<GoodsDraft> pageResult = wrapper.page(pageParam);

        PageVo<GoodsDraftVo> goodsDraftVo = page(pageResult);

        return goodsDraftVo;
    }

    /**
     * 根据id删除
     * @param id 草稿id
     * @param userId 用户id
     */
    @Override
    public void deleteByIdWithUid(Long id, Long userId) {
        QueryWrapper<GoodsDraft> wrapper = new QueryWrapper<>();
        wrapper
                .eq("id", id)
                .eq("createUserId", userId);
        boolean flag = remove(wrapper);
        if(!flag) {
            throw new ShopManageException("删除失败", ResultCodeEnum.FAIL.getCode());
        }
    }

    /**
     * 批量删除
     * @param ids 草稿id
     * @param userId 用户id
     */
    @Override
    public void deleteByIdsWithUid(List<Long> ids, Long userId) {
        QueryWrapper<GoodsDraft> wrapper = new QueryWrapper<>();
        wrapper
                .in("id", ids)
                .eq("createUserId", userId);
        boolean flag = remove(wrapper);
        if(!flag) {
            throw new ShopManageException("删除失败", ResultCodeEnum.FAIL.getCode());
        }
    }

    /**
     * 编辑草稿
     * @param draftId 草稿id
     * @return
     */
    @Override
    public GoodsDraft goodsEditing(Long draftId,Long userId) {


        GoodsDraft goodsDraft = goodsDraftMapper.getGoodsDraft(draftId,userId);
        if (goodsDraft == null) {
            throw new ShopManageException("草稿不存在", ResultCodeEnum.FAIL.getCode());
        }
        return goodsDraft;
    }

    /**
     * 分页通用转换
     */
    private PageVo<GoodsDraftVo> page(Page<GoodsDraft> page) {
        List<GoodsDraft> records = page.getRecords();
        List<GoodsDraftVo> goodsDraftVos = records.stream().map(goodsDraft -> {
            GoodsDraftVo goodsDraftVo = new GoodsDraftVo();
            BeanUtils.copyProperties(goodsDraft, goodsDraftVo);
            //设置管理人名称
            String name = userFeignService.selectNameById(goodsDraft.getCreateUserId());
            goodsDraftVo.setManageUserName(name);

            return goodsDraftVo;
        }).collect(Collectors.toList());
        PageVo<GoodsDraftVo> goodsDraftVoPageVo = new PageVo<>();
        BeanUtils.copyProperties(page, goodsDraftVoPageVo);
        goodsDraftVoPageVo.setPages(page.getPages());
        goodsDraftVoPageVo.setData(goodsDraftVos);

        return goodsDraftVoPageVo;
    }

    //    保存不能运送的城市
    private void saveNonDeliverableCityList(GoodsDraft goodsDraft, List<String> nonDeliverPostalCodeList) {
        if(nonDeliverPostalCodeList != null && nonDeliverPostalCodeList.size() != 0){
            nonDeliverableCityList = new ArrayList<>();
           for(String noDeliverPostalCode : nonDeliverPostalCodeList){
               NonDeliverableCityDraft nonDeliverableCityDraft = new NonDeliverableCityDraft();
               nonDeliverableCityDraft.setGoodsDraftId(goodsDraft.getId());
               nonDeliverableCityDraft.setPostalCode(noDeliverPostalCode);
               nonDeliverableCityList.add(nonDeliverableCityDraft);
           }
           nonDeliverableCityDraftService.saveOrUpdateBatch(nonDeliverableCityList);
        }
    }
    //保存库存城市
    private void saveStorageList(GoodsDraft goodsDraft, List<String> storagePostalCodeList) {
        if(storagePostalCodeList != null && storagePostalCodeList.size() != 0){
             storagecitiesList = new ArrayList<>();
            for(String storagePostalCode : storagePostalCodeList){
                StoragecitiesDraft storagecitiesDraft = new StoragecitiesDraft();
                storagecitiesDraft.setGoodsDraftId(goodsDraft.getId());
                storagecitiesDraft.setPostalCode(storagePostalCode);
                storagecitiesList.add(storagecitiesDraft);
            }
            storagecitiesDraftService.saveOrUpdateBatch(storagecitiesList);
        }
    }

}
